<!doctype html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <style>
    body {
      padding: 0px;
      margin: 0px;
      overflow: hidden;
    }

    #cas {
      display: block;
      border: 1px solid;
      margin: auto;
      background-color: #000
    }

    .showBg {
      background-color: transparent !important;
    }

    .showSomething {
      position: fixed;
      left: 20px;
      top: 20px;
    }

    .game {
      width: 700px;
      margin: auto;
      height: 100%;
      position: relative;
    }

    .movebg {
      width: 100%;
      height: 200%;
      background: url(image/bg_1_1.jpg);
      background-size: 100% 50%;
      position: absolute;
      top: 0px;
      transform: translateY(-50%);
      -webkit-transform: translateY(-50%);
      -moz-transform: translateY(-50%);
      -webkit-animation: bganimate 10s infinite linear;
      animation: bganimate 10s infinite linear;
      -moz-animation: bganimate 10s infinite linear;
      z-index: -1;
    }

    #point {
      width: 100%;
      height: 50px;
      position: absolute;
      top: 0px;
      color: #FFF;
      font: 20px "微软雅黑";
      display: none;
    }

    #gameStart {
      position: absolute;
      width: 100%;
      height: 90px;
      text-align: center;
      color: #FFF;
      font: 20px "微软雅黑";
      top: 410px;
      display: none;
    }

    #gameStart #gs-start {
      display: inline-block;
      width: 180px;
      height: 60px;
      background-color: #CCC;
      color: #000;
      cursor: pointer;
      line-height: 60px;
      border-radius: 10px;
      border: 5px solid #FFF;
    }

    #gameStart #gs-start:hover {
      color: #f00;
    }

    #god {
      position: absolute;
      display: block;
      right: -150px;
      top: 100px;
      width: 140px;
      text-align: center
    }

    #verygod {
      position: absolute;
      display: block;
      right: -150px;
      top: 150px;
      width: 140px;
      text-align: center
    }

    #pretygod {
      position: absolute;
      display: block;
      right: -150px;
      top: 200px;
      width: 140px;
      text-align: center
    }

    #nogod {
      position: absolute;
      display: block;
      right: -150px;
      top: 250px;
      width: 140px;
      text-align: center
    }

    @-webkit-keyframes bganimate {
      from {
        -webkit-transform: translateY(-50%);
      }
      to {
        -webkit-transform: translateY(0);
      }
    }

    @-moz-keyframes bganimate {
      from {
        -webkit-transform: translateY(-50%);
      }
      to {
        -webkit-transform: translateY(0);
      }
    }
  </style>
  <title>飞机游戏</title>
</head>

<body>
  <div class="game">
    <div id="gameStart">
      <span id="gs-start">游戏开始</span><br><br>
      <span>游戏说明：方向键移动，按“Z”“C”键旋转飞机</span>
    </div>
    <div class="movebg"></div>
    <canvas id='cas' width="700" height="750">您的浏览器不支持canvas，请更新浏览器</canvas>
    <button id="god">最高属性</button>
    <button id="verygod">超神属性</button>
    <button id="pretygod">全范围</button>
    <button id="nogod">OMG！！！！</button>
    <div class="showSomething">
      <div id="booms">爆炸使用情况(已使用/缓存量)：</div>
      <div id="missle">子弹使用情况(已使用/缓存量)：</div>
    </div>
  </div>
  <script src="js/data.js"></script>
  <script src="js/loading.js"></script>
  <script src="js/allSprite.js"></script>
  <script>
    var canvas = document.getElementById("cas");
    canvas.height = window.innerHeight;
    var ctx = canvas.getContext('2d');

    var img = new Image(),
      boomDom = document.getElementById("booms"),
      missleDom = document.getElementById("missle"),
      gS = document.getElementById("gameStart"),
      gss = document.getElementById("gs-start");

    window.RAF = (function() {
      return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback) {
        window.setTimeout(callback, 1000 / 60);
      };
    })();

    Array.prototype.foreach = function(callback) {
      for (var i = 0; i < this.length; i++) {
        callback.apply(this[i], [i]);
      }
    }

    var sprites = [],
      missles = [],
			booms = [],
			foods = [],
      badPlanNum = 30,
      point = 0,
      myplan = null,
      foodDate = null,
      dieNum = 0;

    // 随机掉落物品的列表
    var godTimeout;
    var foodMaps = {
      LevelUP: {
        weight: 30,
        effect() {
          myplan.fireLevel = myplan.fireLevel >= 4 ? myplan.fireLevel : myplan.fireLevel + 1;
        }
      },
      SpeedUP: {
        weight: 30,
        effect() {
          myplan.firePerFrame = myplan.firePerFrame <= 10 ? 10 : myplan.firePerFrame - 10;
        }
      },
      God: {
        weight: 30,
        effect() {
          clearTimeout(godTimeout);
          myplan.god = true;
          godTimeout = setTimeout(function() {
            myplan.god = false
          }, 15000);
        }
      },
      Boom: {
        weight: 30,
        effect() {
          sprites.foreach(function() {
            var bp = this;
            if (bp.name === "badPlan" && bp.visible) {
              bp.visible = false;
              point += bp.badKind;
              boom(bp);
            }
          });
        }
      }
    };
    // 计算每种食物命中的概率
    var foodAllWeight = 0;
		var currentProb = 0;
    Object.keys(foodMaps).forEach(key => foodAllWeight += foodMaps[key].weight);
    Object.keys(foodMaps).forEach(key => {
      var probility = foodMaps[key].weight / foodAllWeight;
      foodMaps[key].start = currentProb;
      foodMaps[key].end = currentProb + probility;
      currentProb = foodMaps[key].end;
    });

    function keyHandle(e, result) {
      switch (e.keyCode) {
        //case 88:myplan.fire = result;
        //break;
        case 90:
          myplan.rotateLeft = result;
          break;
        case 67:
          myplan.rotateRight = result;
          break;
        case 37:
          myplan.toLeft = result;
          break;
        case 38:
          myplan.toTop = result;
          break;
        case 39:
          myplan.toRight = result;
          break;
        case 40:
          myplan.toBottom = result;
          break;
      }
    }

    window.onkeydown = function(event) {
      keyHandle(event, true);
    }

    window.onkeyup = function(event) {
      keyHandle(event, false);
    }

    // 作弊器
    document.getElementById("god").onclick = function() {
      if (myplan) {
        myplan.god = true;
        myplan.fireLevel = 4;
        myplan.firePerFrame = 10;
      }
    }
    document.getElementById("verygod").onclick = function() {
      if (myplan) {
        myplan.god = true;
        myplan.fireLevel = 10;
        myplan.firePerFrame = 10;
      }
    }
    document.getElementById("pretygod").onclick = function() {
      if (myplan) {
        myplan.god = true;
        myplan.fireLevel = 40;
        myplan.firePerFrame = 50;
      }
    }
    document.getElementById("nogod").onclick = function() {
      if (myplan) {
        myplan.god = true;
        myplan.fireLevel = 40;
        myplan.firePerFrame = 5;
      }
    }

    function boom(plan) {
      for (var j = 0; j < booms.length; j++) {
        if (!booms[j].visible) {
          booms[j].left = plan.left;
          booms[j].top = plan.top;
          booms[j].visible = true;

          var audio = document.getElementsByTagName("audio");
          for (var i = 0; i < audio.length; i++) {
            if (audio[i].src.indexOf("boom") >= 0 && (audio[i].paused || audio[i].ended)) {
              audio[i].play();
              break;
            }
          }
          break;
        }
      }
    }

    var stage = {
      init: function() {
        var _this = this;
        this.loading = new Loading(datas, canvas, function() {
          gS.style.display = "block";
          canvas.className = "showBg"
          document.getElementById("bgm").play();
          gss.addEventListener("click", function() {
            gS.style.display = "none";
            _this.addElement();
          }, false)
        });
      },

      addElement: function() {
        for (var i = 0; i < 50; i++) {
          var x = Math.random() * canvas.width;
          var y = Math.random() * 2 * canvas.height - canvas.height;
          var star = new Sprite("star", starPainter, starBehavior);
          star.top = y;
          star.left = x;
          sprites.push(star);
        }

        for (var i = 0; i < badPlanNum; i++) {
          var x = Math.random() * (canvas.width - 2 * planSize().w) + planSize().w;
          var y = Math.random() * canvas.height - canvas.height;
          var badPlan = new Sprite("badPlan", badPlanPainter, badPlanBehavior);
          badPlan.top = y;
          badPlan.left = x;
          sprites.push(badPlan);
        }

        for (var i = 0; i < 400; i++) {
          var missle = new Sprite("missle", misslePainter, missleBehavior);
          missle.visible = false;
          missles.push(missle);
        }

        for (var i = 0; i < badPlanNum; i++) {
          var img = new Image();
          img.src = "image/explosion.png";
          var boom = new Sprite("boom", new SpriteSheetPainter(explosionCells, false, function() {
            this.visible = false;
          }, img));
          boom.visible = false;
          booms.push(boom);
        }

				for (var i = 0; i < 5; i++) {
					var eatfood = new Sprite("food", foodPainter, foodBehavior);
					eatfood.left = Math.random() * canvas.width - 60 + 30;
					eatfood.top = -30;
					eatfood.visible = false;
					sprites.push(eatfood);
					foods.push(eatfood);
        }

        img.src = "image/ship.png"
        myplan = new Sprite("plan", new controllSpriteSheetPainter(planCells, img), planBehavior);
        myplan.left = canvas.width / 2;
        myplan.top = canvas.height - (planSize().h / 2 + 10);
        sprites.push(myplan);
      },

      myplanReborn: function(myplan) {
        setTimeout(function() {
          myplan.visible = true;
          myplan.left = canvas.width / 2;
          myplan.top = canvas.height - (planSize().h / 2 + 10);
          myplan.fireLevel = 1;
          myplan.rotateAngle = 0;
          myplan.god = true;
          setTimeout(function() {
            myplan.god = false;
          }, 5000)
        }, 1000)
      },

      update: function() {
        var stage = this;
        var boomnum = 0,
          misslenum = 0;

        this.loading.loop();
        if (this.loading.getComplete()) {
          ctx.clearRect(0, 0, canvas.width, canvas.height);
        }
        missles.foreach(function() {
          var missle = this;
          sprites.foreach(function() {
            var bp = this;
            if (bp.name === "badPlan" && bp.visible && missle.visible) {
              var juli = Math.sqrt(Math.pow(missle.left - bp.left, 2) + Math.pow(missle.top - bp.top, 2));
              if (juli < (planSize().w / 2 + missle.width / 2) && missle.isgood) {
                missle.visible = false;
                bp.blood -= 50;
                if (bp.blood <= 0) {
                  bp.visible = false;
                  point += bp.badKind;
                  boom(bp)
                }
              }
            }
          });

          if (missle.visible) {
            if (!missle.isgood && myplan.visible && !myplan.god) {
              var juli = Math.sqrt(Math.pow(missle.left - myplan.left, 2) + Math.pow(missle.top - myplan.top, 2));
              if (juli < (planSize().w / 2 + 3)) {
                myplan.visible = false;
                dieNum++;
                missle.visible = false;
                boom(myplan)
                stage.myplanReborn(myplan)
              }
            }
            misslenum++;
            this.paint();
          }
        });

        booms.foreach(function() {
          if (this.visible) {
            boomnum++;
            this.paint();
          }
        })

        sprites.foreach(function() {
          if (this.name === "food" && this.visible) {
            var tjuli = Math.sqrt(Math.pow(this.left - myplan.left, 2) + Math.pow(this.top - myplan.top, 2));
            if (tjuli < (myplan.width / 2 + this.width / 2)) {
              this.visible = false;
              foodMaps[this.kind].effect();
            }
          }

          if (this.name === "badPlan" && myplan.visible && !myplan.god) {
            var juli = Math.sqrt(Math.pow(this.left - myplan.left, 2) + Math.pow(this.top - myplan.top, 2));
            if (juli < planSize().w) {
              myplan.visible = false;
              dieNum++;
              this.visible = false;
              boom(this)
              boom(myplan)
              stage.myplanReborn(myplan);
            }
          }

          this.paint();
        });

        if (myplan) {
          ctx.fillStyle = "#FFF"
          ctx.font = "18px 微软雅黑";
          ctx.textAlign = "left";
          ctx.textBaseline = "middle";
          ctx.fillText("Level:" + (myplan.fireLevel === 4 ? "Max" : myplan.fireLevel) + "        Speed:" + ((80 - myplan.firePerFrame) === 70 ? "Max" : (80 - myplan.firePerFrame)), 0, canvas.height - 18);
          ctx.fillText("Points:" + point + "     死亡次数:" + dieNum, 0, 18);
          ctx.textAlign = "right";
          ctx.fillText("Tips:按方向键:移动 ，按“Z”“C”键旋转飞机", canvas.width - 10, 18);

          if (foodDate === null) {
            foodDate = new Date();
          } else {
            var nowFoodDate = new Date();
            if (nowFoodDate - foodDate > 4000) {
              // 随机抛出食物
							var createFood = Math.random() < 0.5 ? true : false;
							var eatfood = foods.find(f => !f.visible);
              if (createFood && eatfood) {
                eatfood.left = Math.random() * canvas.width - 60 + 30;
                eatfood.top = -30;
								eatfood.visible = true;

                var random = Math.random();
                var foodList = Object.keys(foodMaps);
                for (var i = 0; i < foodList.length; i++) {
									var food = foodMaps[foodList[i]];
                  if (random >= food.start && random <= food.end) {
                    eatfood.kind = foodList[i];
                  }
                }
							}

              foodDate = nowFoodDate;
            }
          }
        }

        boomDom.innerHTML = "爆炸使用率(已使用/存储总量):" + boomnum + "/" + booms.length;
        missleDom.innerHTML = "子弹使用率(已使用/存储总量):" + misslenum + "/" + missles.length;
      },

      loop: function() {
        var _this = this;
        this.update();
        RAF(function() {
          _this.loop();
        });
      },

      start: function() {
        this.init();
        this.loop();
      }
    }

    stage.start();
  </script>
</body>

</html>